﻿package com.singlenotion.display.sliders 
{
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import gs.easing.Elastic;
	import gs.easing.Sine;
	import gs.TweenMax;
	
	/**
	 * ...
	 * @author Adam Jowett (Single Notion)
	 */
	public class HorizontalSlider extends MovieClip
	{
		protected var _items:Array;
		protected var _sliderWidth:Number;
		protected var _sliderHeight:Number;
		protected var _leftArrow:Sprite;
		protected var _rightArrow:Sprite;
		protected var _sliderHolder:Sprite;
		protected var _showMask:Boolean;
		protected var _maskBuffer:Number;
		protected var _showArrows:Boolean;
		protected var _arrowColour:int;
		protected var _arrowOverColour:int;
		protected var _leftArrowBuffer:Number;
		protected var _rightArrowBuffer:Number;
		protected var _arrowVerticalOffset:Number;
		protected var _currentID:int;
		protected var _targetID:int;
		protected var _tweenTime:Number;
		
		public function HorizontalSlider(	$items:Array, $width:Number, $height:Number, $tweenTime:Number, $showmask:Boolean = false, $showArrows:Boolean = true, 
											$maskBuffer:Number = 0, $arrowColour:int = 0xFFFFFF, $arrowOverColour:int = 0x00CC33, $leftArrowBuffer:Number = 5, 
											$rightArrowBuffer:Number = 5, $arrowVerticalOffset:Number = 0) 
		{
			_items = $items;
			_sliderWidth = $width;
			_sliderHeight = $height;
			_showMask = $showmask;
			_maskBuffer = $maskBuffer;
			_showArrows = $showArrows;
			_arrowColour = $arrowColour;
			_arrowOverColour = $arrowOverColour;
			_leftArrowBuffer = $leftArrowBuffer;
			_rightArrowBuffer = $rightArrowBuffer;
			_arrowVerticalOffset = $arrowVerticalOffset;
			_tweenTime = $tweenTime;
			
			addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
		}
		
		/**********************************************************************************/
				
		protected function init($e:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			addEventListener(Event.REMOVED_FROM_STAGE, destroy, false, 0, true);
			
			_currentID = 0;
			
			build();
		}
		
		public function destroy($e:Event):void
		{
			removeEventListener(Event.REMOVED_FROM_STAGE, destroy);
		}
		
		/***********************************************************************************/
		
		protected function build():void
		{
			_sliderHolder = new Sprite();
			addChild(_sliderHolder);
			
			var totalWidth:Number = 0;
			
			for each (var item:* in _items)
			{
				_sliderHolder.addChild(item);
				item.x = totalWidth;
				
				totalWidth += _sliderWidth;
			}
			
			if (_showArrows) addArrows();
			if (_showMask) addMask();
			
			goto(1);
			
			dispatchEvent(new Event(SliderEvents.CREATED, true, true));
		}
		
		protected function addArrows():void
		{
			var lineWidth:Number = 3;
			var arrowWidth:Number = 8;
			var arrowHeight:Number = 22;
			
			_leftArrow = new Sprite();
			_leftArrow.graphics.clear();
			_leftArrow.graphics.beginFill(0x990000, 0);
			_leftArrow.graphics.drawRect(0, 0, arrowWidth + lineWidth, arrowHeight);
			_leftArrow.graphics.endFill();
			_leftArrow.graphics.lineStyle(lineWidth, _arrowColour);
			_leftArrow.graphics.moveTo(arrowWidth, 0);
			_leftArrow.graphics.lineTo(0, arrowHeight / 2);
			_leftArrow.graphics.lineTo(arrowWidth, arrowHeight);
			
			_leftArrow.buttonMode = true;
			_leftArrow.x = _leftArrowBuffer;
			_leftArrow.y = _sliderHeight / 2 - _leftArrow.height / 2 + _arrowVerticalOffset;
			
			_rightArrow = new Sprite();
			_rightArrow.graphics.clear();
			_rightArrow.graphics.beginFill(0x990000, 0);
			_rightArrow.graphics.drawRect(0, 0, arrowWidth + lineWidth, arrowHeight);
			_rightArrow.graphics.endFill();
			_rightArrow.graphics.lineStyle(lineWidth, _arrowColour);
			_rightArrow.graphics.lineTo(arrowWidth, arrowHeight / 2);
			_rightArrow.graphics.lineTo(0, arrowHeight);
			
			_rightArrow.buttonMode = true;
			_rightArrow.y = _leftArrow.y;
			_rightArrow.x = _sliderWidth - _rightArrow.width - _rightArrowBuffer;
			
			addChild(_leftArrow);
			addChild(_rightArrow);
			
			adjustArrows();
		}
		
		protected function leftArrowListener($e:MouseEvent):void 
		{
			_leftArrow.removeEventListener(MouseEvent.CLICK, leftArrowListener);
			_currentID--;
			goto(_currentID + 1);
		}
		
		protected function rightArrowListener($e:MouseEvent):void 
		{
			_rightArrow.removeEventListener(MouseEvent.CLICK, rightArrowListener);
			_currentID++;
			goto(_currentID + 1);
		}
		
		protected function adjustSlider():void
		{
			if (_showArrows) adjustArrows();
			dispatchEvent(new Event(SliderEvents.SLIDE_COMPLETE, true, true));
		}
		
		protected function adjustArrows():void
		{
			_leftArrow.addEventListener(MouseEvent.ROLL_OVER, arrowOverListener, false, 0, true);
			_leftArrow.addEventListener(MouseEvent.ROLL_OUT, arrowOutListener, false, 0, true);
			_leftArrow.addEventListener(MouseEvent.CLICK, leftArrowListener, false, 0, true);
			
			_rightArrow.addEventListener(MouseEvent.ROLL_OVER, arrowOverListener, false, 0, true);
			_rightArrow.addEventListener(MouseEvent.ROLL_OUT, arrowOutListener, false, 0, true);
			_rightArrow.addEventListener(MouseEvent.CLICK, rightArrowListener, false, 0, true);
			
			_leftArrow.visible = _sliderHolder.x < 0;
			_rightArrow.visible = (_sliderHolder.x > -(_sliderWidth * (_items.length - 1)));
		}
		
		protected function arrowOverListener($e:MouseEvent):void 
		{
			TweenMax.to($e.target, 0.3, { tint:_arrowOverColour } );
		}
		
		protected function arrowOutListener($e:MouseEvent):void 
		{
			TweenMax.to($e.target, 0.3, { removeTint:true } );
		}
		
		protected function addMask():void
		{
			var sliderMask:Sprite = new Sprite();
			sliderMask.graphics.clear();
			sliderMask.graphics.beginFill(0x990000, 0.5);
			sliderMask.graphics.drawRect(0, 0, _sliderWidth - (_maskBuffer * 2) - 4, _sliderHeight);
			sliderMask.graphics.endFill();
			sliderMask.x = _maskBuffer;
			
			addChild(sliderMask);
			
			_sliderHolder.mask = sliderMask;
		}
		
		public function getItem($id:int):* { return _items[$id]; }
		
		public function getCurrentItem():* { return _items[_currentID]; }
		
		public function goto($id:int):void
		{
			var index:int = $id - 1;
			
			dispatchEvent(new Event(SliderEvents.SLIDE_BEGIN, true, true));
			
			var i:int;
			var l:int = _items.length;
			for (i = 0; i < l; i++) {
				if (i == index) {
					TweenMax.to(_items[i], _tweenTime, { autoAlpha:1, blurFilter: { blurX:0, blurY:0 }, colorMatrixFilter: { colorize:0x000000, amount:0 }} );
				} else if (Math.abs(i-index) == 1) { //i == index + 1 || i == index - 1) {
					TweenMax.to(_items[i], _tweenTime, { autoAlpha:1, blurFilter:{blurX:5, blurY:5}, colorMatrixFilter: { colorize:0x000000, amount:0.7 }} );
				} else {
					TweenMax.to(_items[i], _tweenTime / 2, { autoAlpha:0 } );
				}
			}
			
			TweenMax.to(_sliderHolder, _tweenTime, { x: -(_sliderWidth * ($id - 1)), onComplete:adjustSlider } );
			
			_currentID = $id - 1;
		}
		
		public function get currentID():int { return _currentID; }
		
		public function get items():Array { return _items; }
	}
	
}